package com.boarsoft.boar.batch;

import java.util.Map;

import com.boarsoft.bean.ReplyInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.boarsoft.boar.batch.bean.BatchAppStat;
import com.boarsoft.boar.batch.entity.BatchExecution;
import com.boarsoft.boar.batch.service.BatchBrokerService;
import com.boarsoft.common.util.InetUtil;
import com.boarsoft.flow.core.SimpleFlow;
import com.boarsoft.flow.core.SimpleFlowEngine;
import com.boarsoft.serialize.TaggedJsonSerializer;

/**
 * 流程式批量的执行接口<br>
 * 无论是新跑，续跑，还是重跑，对于流程引擎而言，总是启动新的流程
 * 
 * @author Mac_J
 *
 */
public class SimpleFlowBatchBroker implements BatchBrokerService {
	private static final Logger log = LoggerFactory.getLogger(SimpleFlowBatchBroker.class);

	protected SimpleFlowEngine simpleFlowEngine;

	@Override
	public Object stat() {
		// TODO 返回当前节点上正在执行或挂起中的批量任务
		BatchAppStat stat = new BatchAppStat(simpleFlowEngine.getCatalog());
		// 取运行中的所有批量
		Map<String, Map<String, SimpleFlow>> tm = simpleFlowEngine.getTimeMap();
		for (Map<String, SimpleFlow> im : tm.values()) {
			// 只要有一个实例就列出来
			if (im == null || im.isEmpty()) {
				continue;
			}
			// 每个批量最多取50个实例
			int i = 0;
			for (String id : im.keySet()) {
				if (i < 50) {
					SimpleFlow f = im.get(id);
					stat.addInst(this.convert(f));
					i++;
				} else {
					break;
				}
			}
		}
		// SimpleFlowPersister fp = simpleFlowEngine.getPersister();
		// 查询持久化存储中的批量任务（挂起的任务）
		// PagedResult<SimpleFlow> pr = fp.list(SimpleFlow.STATUS_SUSPEND, 1,
		// 50);
		return stat;
	}

	protected BatchExecution convert(SimpleFlow f) {
		BatchExecution x = new BatchExecution();
		x.setAddr(InetUtil.getAddr());
		x.setCatalog(simpleFlowEngine.getCatalog());
		x.setCode(f.getFlowId());
		x.setEndTime(f.getEndTime());
		x.setEntry(f.getEntry());
		x.setId(f.getId());
		// x.setInfoId(f.get);
		// x.setNo(no);
		// x.setParams(params);
		x.setStartTime(f.getStartTime());
		//
		switch (f.getStatus()) {
		case SimpleFlow.STATUS_EXECUTING:
			x.setStatus(BatchExecution.STATUS_RUNNING);
			break;
		case SimpleFlow.STATUS_FALED:
			x.setStatus(BatchExecution.STATUS_FAILED);
			break;
		case SimpleFlow.STATUS_NEW:
			x.setStatus(BatchExecution.STATUS_NEW);
			break;
		case SimpleFlow.STATUS_STOPPED:
			x.setStatus(BatchExecution.STATUS_STOPPED);
			break;
		case SimpleFlow.STATUS_SUCCESS:
			x.setStatus(BatchExecution.STATUS_SUCCESS);
			break;
		case SimpleFlow.STATUS_SUSPEND:
			x.setStatus(BatchExecution.STATUS_SUSPEND);
			break;
		case SimpleFlow.STATUS_TIMEOUT:
			x.setStatus(BatchExecution.STATUS_TIMEOUT);
			break;
		}
		//
		x.setPhrase(f.getStep());
		// x.setType(f.get);
		return x;
	}

	@Override
	public Object startAll(BatchExecution exe) throws Exception {
		return this.start(exe);
	}

	@Override
	public String start(BatchExecution exe) throws Exception {
		return this.execute(exe);
	}

	@Override
	public String resume(BatchExecution exe) throws Exception {
		return this.execute(exe);
	}

	@Override
	public String redo(BatchExecution exe) throws Exception {
		return this.execute(exe);
	}

	public String execute(final BatchExecution exe) throws Exception {
		log.info("Execute batch {}", exe);
		String params = exe.getParams();
		Object po = TaggedJsonSerializer.deserialize1(params);
		simpleFlowEngine.execute(exe.getCode(), exe.getId(), po);
		return InetUtil.getAddr();
	}

	@Override
	public void cancel(BatchExecution exe, boolean force) throws Exception {
		SimpleFlow fo = null;
		try {
			fo = simpleFlowEngine.getFlow(exe.getCode(), exe.getId());
		} catch (Throwable e) {
			log.error("Error on get flow {}", exe, e);
			return;
		}
		if (fo == null) {
			return;
		}
		simpleFlowEngine.stop(fo);
	}

	public SimpleFlowEngine getSimpleFlowEngine() {
		return simpleFlowEngine;
	}

	public void setSimpleFlowEngine(SimpleFlowEngine simpleFlowEngine) {
		this.simpleFlowEngine = simpleFlowEngine;
	}
}